<?php

namespace app\model;

use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Model;
use think\model\relation\BelongsTo;

class PayRecord extends Model
{
    // 设置当前模型对应的数据表
    protected $name = 'pay_record';
    // 设置当前模型主键
    protected $pk = 'id';

    //支付商户
    const PAY_MERCHANT_LIUYIJUCHANG = 1;//比翼鸟剧场
    const PAY_MERCHANT_LIUYIWENHUA = 2;//比翼鸟网络科技
    const PAY_MERCHANT_CHENGZIJUCHANG = 3;//比翼鸟剧场
    const PAY_MERCHANT_LIUYICHUANMEI = 4;//比翼鸟传媒
    const PAY_MERCHANT_ZHANGZHONGYUN = 5;//掌中付第三方
    const PAY_MERCHANT_LIUYIDUANJU = 6;//比翼鸟短剧
    const PAY_MERCHANT_LIUYI = 7;//微信官方-比翼鸟
    const PAY_MERCHANT_LIUYIKANHAOJU = 8;//微信官方-比翼鸟看好剧
    const PAY_MERCHANT_LIUYIXIAOJUCHANG = 9;//微信官方-比翼鸟小剧场
    const PAY_MERCHANT_MIHUALIUYI = 10;//米花比翼鸟
    const PAY_MERCHANT_MIHUADALIANQUMAN = 11;//米花大连趣漫
    const PAY_MERCHANT_MIHUAXINGCAN = 12;//米花星灿
    const PAY_MERCHANT_MIHUAAPPLETJUMP_LIUYI = 13;//米花小程序跳转-比翼鸟
    const PAY_MERCHANT_MIHUAAPPLETJUMP_DALIANQUMAN = 14;//米花小程序跳转-大连趣漫
    const PAY_MERCHANT_VIRTUALPAYMENT = 15;//小程序虚拟支付
    const PAY_MERCHANT_MIHUA_H5_LIUYI = 16;//米花H5-比翼鸟
    const PAY_MERCHANT_MIHUA_H5_PINZHONG = 17;//米花H5-品众
    const PAY_MERCHANT_SAOMAFU = 18;//扫码富第三方

    const PAY_MERCHANT_NNYY_1 = 20; //微信官方-南宁源誉科技
    const PAY_MERCHANT_NNYY_2 = 21; //微信官方-南宁源誉科技
    const PAY_MERCHANT_DY_GENERAL = 30; //抖音通用支付
    
    //支付商户数组
    const PAY_MERCHANT_ARR = [
        self::PAY_MERCHANT_LIUYIJUCHANG => '微信官方-比翼鸟剧场',
        self::PAY_MERCHANT_LIUYIWENHUA => '微信官方-比翼鸟文化',
        self::PAY_MERCHANT_CHENGZIJUCHANG => '微信官方-橙子剧场',
        self::PAY_MERCHANT_LIUYICHUANMEI => '微信官方-比翼鸟传媒',
        self::PAY_MERCHANT_ZHANGZHONGYUN => '掌中付第三方',
        self::PAY_MERCHANT_LIUYIDUANJU => '微信官方-比翼鸟短剧',
        self::PAY_MERCHANT_LIUYI => '微信官方-比翼鸟',
        self::PAY_MERCHANT_LIUYIKANHAOJU => '微信官方-比翼鸟看好剧',
        self::PAY_MERCHANT_LIUYIXIAOJUCHANG => '微信官方-比翼鸟小剧场',
        self::PAY_MERCHANT_MIHUALIUYI => '米花-比翼鸟',
        self::PAY_MERCHANT_MIHUADALIANQUMAN => '米花-大连趣漫',
        self::PAY_MERCHANT_MIHUAXINGCAN => '米花-星灿',
        self::PAY_MERCHANT_MIHUAAPPLETJUMP_LIUYI => '米花小程序跳转-比翼鸟',
        self::PAY_MERCHANT_MIHUAAPPLETJUMP_DALIANQUMAN => '米花小程序跳转-大连趣漫',
        self::PAY_MERCHANT_VIRTUALPAYMENT => '微信小程序虚拟支付',
        self::PAY_MERCHANT_MIHUA_H5_LIUYI => '米花H5-比翼鸟',
        self::PAY_MERCHANT_MIHUA_H5_PINZHONG => '米花H5-品众',
        self::PAY_MERCHANT_SAOMAFU => '扫码富第三方',
        self::PAY_MERCHANT_NNYY_1 => '微信官方-南宁源誉科技',
        self::PAY_MERCHANT_NNYY_2 => '微信官方-南宁源誉科技'
    ];
    
    //充值类型
    const RECHARGE_TYPE_ARR = [
        1 => '普通充值',
        2 => '年卡会员',
        3 => '180天会员',
        4 => '90天会员',
        5 => '60天会员',
        6 => '30天会员',
        7 => '10天会员',
        8 => '7天会员',
        9 => '签到',
        10 => '分享',
        11 => '会员三天',
        12 => '解锁全集',
        13 => '活动充值',
        14 => '广告奖励',
        15 => '1天会员',
    ];
    
    //米花支付对应的enum key
    const PAY_MERCHANT_MIHUA_ARR = [
        self::PAY_MERCHANT_MIHUALIUYI => 'wechat_third_party_applet_payment1',
        self::PAY_MERCHANT_MIHUADALIANQUMAN => 'wechat_third_party_applet_payment2',
        self::PAY_MERCHANT_MIHUAXINGCAN => 'wechat_third_party_applet_payment3',
        self::PAY_MERCHANT_MIHUAAPPLETJUMP_LIUYI => 'wechat_applet_jump_mihua_liuyi',
        self::PAY_MERCHANT_MIHUAAPPLETJUMP_DALIANQUMAN => 'wechat_applet_jump_mihua_dalianquman',
        self::PAY_MERCHANT_MIHUA_H5_LIUYI => 'mihua_h5_liuyi',
        self::PAY_MERCHANT_MIHUA_H5_PINZHONG => 'mihua_h5_pinzhong',
    ];
    //米花小程序跳转支付对应的enum key
    const PAY_MERCHANT_MIHUA_JUMP_ARR = [
        self::PAY_MERCHANT_MIHUAAPPLETJUMP_LIUYI => 'wechat_applet_jump_mihua_liuyi',
        self::PAY_MERCHANT_MIHUAAPPLETJUMP_DALIANQUMAN => 'wechat_applet_jump_mihua_dalianquman',
    ];

    //设备类型
    const DEVICE_TYPE_IOS = 1;//ios
    const DEVICE_TYPE_ANDROID = 2;//android
    const DEVICE_TYPE_OTHER = 3;//其他
    const DEVICE_TYPE_ARR = [
        self::DEVICE_TYPE_IOS => 'ios',
        self::DEVICE_TYPE_ANDROID => 'android',
        self::DEVICE_TYPE_OTHER => 'other',
    ];

    //支付产品来源
    const SOURCE_WECHAT_APPLET = 1;//微信小程序支付
    const SOURCE_TIKTOK_APPLET = 2;//抖音小程序支付
    const SOURCE_KUAISHOW_APPLET = 3;//快手小程序支付
    const SOURCE_WECHAT_MP_H5 = 4;//微信公众号H5支付
    const SOURCE_QUICK_APP = 5;//快应用
    const SOURCE_H5 = 6;//H5支付
    const SOURCE_ARR = [
        self::SOURCE_WECHAT_APPLET => '微信小程序支付',
        self::SOURCE_TIKTOK_APPLET => '抖音小程序支付',
        self::SOURCE_KUAISHOW_APPLET => '快手小程序支付',
        self::SOURCE_WECHAT_MP_H5 => '微信公众号H5支付',
        self::SOURCE_QUICK_APP => '快应用',
        self::SOURCE_H5 => 'H5支付',
    ];

    //退款状态
    const REFUND_STATUS_DEFAULT = 0;//退款默认状态
    const REFUND_STATUS_SUCC = 1;//退款成功
    const REFUND_STATUS_FAIL = 2;//退款失败
    const REFUND_STATUS_ARR = [
        self::REFUND_STATUS_SUCC => '退款成功',
        self::REFUND_STATUS_FAIL => '退款失败',
    ];

    //状态
    const STATUS_PENDING = 0;//未支付
    const STATUS_SUCC = 1;//支付成功
    const STATUS_ARR = [
        self::STATUS_PENDING => '未支付',
        self::STATUS_SUCC => '支付成功',
    ];

    /**
     * 新增/更新
     * 
     * @dateTime 2022/08/24
     * @author zhixiang0215@126.com
     * @param array $params
     * @return int
     */
    public function edit($params)
    {
        if (empty($params['id'])) {
            $data = $this::create($params);
            return $data->id;
        }
        $this::update($params);
        return $params['id'];
    }

    /**
     * 根据条件获取数据
     * 
     * @dateTime 2022/09/05
     * @author zhixiang0215@126.com
     * @param array where
     * @param string fields
     * @return array
     */
    public function getInfo(array $where, string $fields = 'id', $order = '')
    {
        //
        $model = $this::where($where)->field($fields);
        if ($order) {
            $model->order($order);
        }
        $data = $model->select();
        return $data ? $data->toArray() : [];
    }

    /**
     * 根据条件获取数据
     * 
     * @dateTime 2022/09/05
     * @author zhixiang0215@126.com
     * @param array where
     * @param string fields
     * @return array
     */
    public function getDataByWhere(array $where, string $fields = 'id', string $order = '')
    {
        $model = $this::where($where)->field($fields);
        if (!empty($order)) {
            $model->order($order);
        }
        $data = $model->find();
        return $data ? $data->toArray() : [];
    }

    // 根据条件获取数量
    public function getCount($where = [])
    {
        $count = $this::where($where)->count();
        return $count;
    }

    // 根据条件统计金额
    public function getSumPrice($where = [])
    {
        $count = $this::where($where)->sum('total_fee');
        return $count;
    }

    // 根据条件统计分组数
    public function getPeopleNumber($where = [], $fields = 'uid')
    {
        $count = $this::where($where)->group($fields)->count();
        return $count;
    }

    // 根据条件获取分页数据
    public function getPagingDataByWhere($where = [], $page = 1, $limit = 10, $fields = 'id, uid, video_id, total_fee', $order = 'id desc')
    {
        $total = $this::where($where)->count();

        if ($total == 0) {
            return ['total' => 0, 'total_page' => 0, 'data' => []];
        }

        $offset = ($page - 1) * $limit;
        if ($offset < 0) $offset = 0;

        $totalPage = ceil($total / $limit);

        $data = $this::where($where)->field($fields)->order($order)->limit($offset, $limit)->select()->toArray();

        return ['total' => $total, 'total_page' => $totalPage, 'data' => $data];
    }

    /**
     * 获取小程序端显示支付文案
     * @param $payRecord
     * @return string
     */
    public static function getPayTextForApplet($payRecord): string
    {
        $type = $payRecord['type'] ?? Money::TYPE_COMMON;
        $number = $payRecord['number'] ?? 1;
        switch ($type){
            //解锁全集
            case Money::TYPE_UNLOCK_ALL:
                $text = '';
                break;
            case Money::TYPE_ONE_YEAR_VIP:
                $text = '年卡会员';
                break;
            case Money::TYPE_HALF_YEAR_VIP:
                $text = '半年会员';
                break;
            case Money::TYPE_SEASON_VIP:
                $text = '季卡会员';
                break;
            case Money::TYPE_60_VIP:
                $text = '60天会员';
                break;
            case Money::TYPE_30_VIP:
                $text = '30天会员';
                break;
            case Money::TYPE_10_VIP:
                $text = '10天会员';
                break;
            case Money::TYPE_7_VIP:
                $text = '7天会员';
                break;
            case Money::TYPE_3_VIP:
                $text = '3天会员';
                break;
            case Money::TYPE_1_VIP:
                $text = '1天会员';
                break;
            default:
                $text = '+ '. $number .' K币';
                break;
        }
        return $text;
    }
       /**
     * 获取小程序端显示支付文案
     * @param $payRecord
     * @return string
     */
    public static function getPayTypeForApplet($payRecord): string
    {
        $type = $payRecord['type'] ?? Money::TYPE_COMMON;
        $number = $payRecord['number'] ?? 1;
        switch ($type){
            //解锁全集
            case Money::TYPE_UNLOCK_ALL:
                $text = 2;
                break;
            case Money::TYPE_ONE_YEAR_VIP:
            case Money::TYPE_HALF_YEAR_VIP:
            case Money::TYPE_SEASON_VIP:
            case Money::TYPE_60_VIP:
            case Money::TYPE_30_VIP:
            case Money::TYPE_10_VIP:
            case Money::TYPE_7_VIP:
            case Money::TYPE_3_VIP:
            case Money::TYPE_1_VIP:
                $text = 3;
                break;
            default:
                $text = 1;
                break;
        }
        return $text;
    }
    /**
     * 关联用户
     * @return BelongsTo
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class, 'uid');
    }

    /**
     * 关联剧
     * @return BelongsTo
     */
    public function video(): BelongsTo
    {
        return $this->belongsTo(Videos::class, 'video_id');
    }

    /**
     * 关联链接
     * @return BelongsTo
     */
    public function link(): BelongsTo
    {
        return $this->belongsTo(Link::class, 'link_id');
    }

    /**
     * 关联公众号
     * @return BelongsTo
     */
    public function officialAccount(): BelongsTo
    {
        return $this->belongsTo(OfficialAccounts::class, 'official_account_id');
    }


    /**
     * 获取分销商名称
     * @param $id
     * @return string
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getDistributor($id): string
    {
        $info = self::find($id);
        return $info->link->responsibilityPerson->name ?? '未知';
    }

    /**
     * 获取公司名称
     * @param $id
     * @return string
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getCompany($id): string
    {
        $info = self::find($id);
        return $info->link->responsibilityPerson->parent->company->name ?? ($info->link->responsibilityPerson->company->name ?? '未知');
    }

    /**
     * 获取充值描述
     * @param $name
     * @param $type
     * @return string
     */
    public static function getPaymentDescription($type,$name): string
    {
        $desc = '';
        switch ($type){
            case Money::TYPE_COMMON:
                $desc.= '充值K币-';
                break;
            case Money::TYPE_ONE_YEAR_VIP:
            case Money::TYPE_HALF_YEAR_VIP:
            case Money::TYPE_SEASON_VIP:
            case Money::TYPE_60_VIP:
            case Money::TYPE_30_VIP:
            case Money::TYPE_10_VIP:
            case Money::TYPE_7_VIP:
            case Money::TYPE_3_VIP:
            case Money::TYPE_1_VIP:
                $desc.= '充值会员-';
                break;
            case Money::TYPE_UNLOCK_ALL:
                $desc.= '解锁全集-';
                break;
            case Money::TYPE_ACTIVITY:
                $desc.= '活动充值-';
                break;
            default:
                $desc.= '充值-';
                break;
        }
        return $desc.$name;
    }
    /**
     * 更新后操作
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public static function onAfterUpdate(PayRecord $model) {
        try {
            $id = $model->getWhere()['id'] ?? 0;
            $payRecord = self::find($id);
            if ($payRecord && $payRecord->activity_id > 0){
                $date = date('Ymd');
                self::saveActivityStatistics($payRecord,$date);
            }
        }catch (\Throwable $e){
            flog([
                'message' => $e->getMessage(),
                'data' => $model->toArray(),
            ],'pay_record_update','error');
        }
    }

    /**
     * 新增后操作
     * @param PayRecord $model
     * @return void
     */
    public static function onAfterInsert(PayRecord $model): void
    {
        try {
            if ($model->activity_id > 0){
                $date = date('Ymd');
                self::saveActivityStatistics($model,$date);
            }
        }catch (\Throwable $e){
            flog([
                'message' => $e->getMessage(),
                'data' => $model->toArray(),
            ],'pay_record_insert','error');
        }
    }

    /**
     * 保存活动统计
     * @param PayRecord $payRecord
     * @param $date
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function saveActivityStatistics(PayRecord $payRecord, $date = null): bool
    {
        $date = $date ?? date('Ymd');
        $types = Money::TYPE_ARR;
        unset($types[Money::TYPE_SIGN],$types[Money::TYPE_SHARE]);
        $activityId = $payRecord->activity_id;
        //充值人数
        $rechargeUv = self::where([
            'activity_id' => $activityId,
            'official_account_id' => $payRecord->official_account_id,
            'status' => self::STATUS_SUCC,
            'consume_date' => $date,
            ['type', 'in', array_keys($types)]
        ])->group(['uid'])->count();
        //点击人数
        $clickUv = self::where([
            'activity_id' => $activityId,
            'official_account_id' => $payRecord->official_account_id,
            'consume_date' => $date,
            ['type', 'in', array_keys($types)]
        ])->group(['uid'])->count();
        //点击次数
        $clickCount = self::where([
            'activity_id' => $activityId,
            'official_account_id' => $payRecord->official_account_id,
            'consume_date' => $date,
            ['type', 'in', array_keys($types)]
        ])->count();
        //充值金额
        $rechargeAmount = self::where([
            'activity_id' => $activityId,
            'official_account_id' => $payRecord->official_account_id,
            'status' => self::STATUS_SUCC,
            'consume_date' => $date,
            ['type', 'in', array_keys($types)]
        ])->sum('total_fee');
        $start = date('Y-m-d',strtotime($date));
        $end = date('Y-m-d 23:59:59',strtotime($date));
        //退款金额
        $refundAmount = RefundRecord::where([
            'refund_record.status' => RefundRecord::STATUS_SUCC,
            ['refund_time', 'between', [$start, $end]]
        ])
        ->withJoin(['payRecord'], 'left')
        ->where([
            'payRecord.activity_id' => $activityId,
            'payRecord.official_account_id' => $payRecord->official_account_id,
        ])
        ->sum('refund_price');
        //充值次数
        $rechargeCount = self::where([
            'activity_id' => $activityId,
            'official_account_id' => $payRecord->official_account_id,
            'status' => self::STATUS_SUCC,
            'consume_date' => $date,
            ['type', 'in', array_keys($types)]
        ])->count();
        return ActivityStatistics::saveData($payRecord,[
            'date' => date('Y-m-d',strtotime($date)),
            'recharge_uv' => $rechargeUv,
            'click_uv' => $clickUv,
            'click_count' => $clickCount,
            'recharge_amount' => $rechargeAmount,
            'refund_amount' => $refundAmount,
            'recharge_count' => $rechargeCount,
        ]);
    }
}